import bus from './bus';
import * as cornerstone from "cornerstone-core";
// import * as cornerstoneTools from "@cornerstonejs/tools";
import cornerstoneTools from "cornerstone-tools";
import _ from 'lodash';
import { useVideo } from "@/store";

/*this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_DOWN_ACTIVATE, this.mouseDownActivate.bind(this));
this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_DOUBLE_CLICK, this.mouseDownActivate.bind(this));
this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_CLICK, this.mouseDownActivate.bind(this));
this.element.addEventListener(cornerstoneTools.EVENTS.CLIP_STOPPED, (e: any) => aa("CLIP_STOPPED", e));
this.element.addEventListener(cornerstoneTools.EVENTS.DOUBLE_TAP, (e: any) => aa("DOUBLE_TAP", e));
this.element.addEventListener(cornerstoneTools.EVENTS.KEY_DOWN, (e: any) => aa("KEY_DOWN", e));
this.element.addEventListener(cornerstoneTools.EVENTS.KEY_PRESS, (e: any) => aa("KEY_PRESS", e));
this.element.addEventListener(cornerstoneTools.EVENTS.KEY_UP, (e: any) => aa("KEY_UP", e));
this.element.addEventListener(cornerstoneTools.EVENTS.LABELMAP_MODIFIED, (e: any) => aa("LABELMAP_MODIFIED", e));
this.element.addEventListener(cornerstoneTools.EVENTS.MEASUREMENT_REMOVED, (e: any) => aa("MEASUREMENT_REMOVED", e));
this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_CLICK, (e: any) => aa("MOUSE_CLICK", e));
this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_DOWN, (e: any) => aa("MOUSE_DOWN", e));
this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_DOWN_ACTIVATE, (e: any) => aa("MOUSE_DOWN_ACTIVATE", e));
this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_DRAG, (e: any) => aa("MOUSE_DRAG", e));
//  this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_MOVE, (e:any) => aa("MOUSE_MOVE", e));
this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_UP, (e: any) => aa("MOUSE_UP", e));
this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_WHEEL, (e: any) => aa("MOUSE_WHEEL", e));
this.element.addEventListener(cornerstoneTools.EVENTS.MULTI_TOUCH_DRAG, (e: any) => aa("MULTI_TOUCH_DRAG", e));
this.element.addEventListener(cornerstoneTools.EVENTS.MULTI_TOUCH_START, (e: any) => aa("MULTI_TOUCH_START", e));
this.element.addEventListener(cornerstoneTools.EVENTS.MULTI_TOUCH_START_ACTIVE, (e: any) => aa("MULTI_TOUCH_START_ACTIVE", e));
this.element.addEventListener(cornerstoneTools.EVENTS.STACK_PREFETCH_DONE, (e: any) => aa("STACK_PREFETCH_DONE", e));
this.element.addEventListener(cornerstoneTools.EVENTS.STACK_PREFETCH_IMAGE_LOADED, (e: any) => aa("STACK_PREFETCH_IMAGE_LOADED", e));
this.element.addEventListener(cornerstoneTools.EVENTS.STACK_SCROLL, (e: any) => aa("STACK_SCROLL", e));
this.element.addEventListener(cornerstoneTools.EVENTS.TAP, (e: any) => aa("TAP", e));
this.element.addEventListener(cornerstoneTools.EVENTS.TOUCH_DRAG, (e: any) => aa("TOUCH_DRAG", e));
this.element.addEventListener(cornerstoneTools.EVENTS.TOUCH_DRAG_END, (e: any) => aa("TOUCH_DRAG_END", e));
this.element.addEventListener(cornerstoneTools.EVENTS.TOUCH_END, (e: any) => aa("TOUCH_END", e));
this.element.addEventListener(cornerstoneTools.EVENTS.TOUCH_PINCH, (e: any) => aa("TOUCH_PINCH", e));
this.element.addEventListener(cornerstoneTools.EVENTS.TOUCH_PRESS, (e: any) => aa("TOUCH_PRESS", e));
this.element.addEventListener(cornerstoneTools.EVENTS.TOUCH_ROTATE, (e: any) => aa("TOUCH_ROTATE", e));
this.element.addEventListener(cornerstoneTools.EVENTS.TOUCH_START, (e: any) => aa("TOUCH_START", e));
this.element.addEventListener(cornerstoneTools.EVENTS.TOUCH_START_ACTIVE, (e: any) => aa("TOUCH_START_ACTIVE", e));
this.element.addEventListener('cornerstonetoolsmousedownactivate', pt.onMousedownActivate)
this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_UP, this.cornerstoneToolsMouseUp.bind(this));
this.element.addEventListener(cornerstone.EVENTS.IMAGE_RENDERED, this.cornerstoneImageRendered.bind(this));
this.element.addEventListener(cornerstone.EVENTS.PRE_RENDER, this.cornerstonePreRender.bind(this));*/


function handleX(x:number, width: number){
  if( x < 0  ) return 0;
  if( x > width ) return width;
  return x;
}
function handleY(y:number, height: number){
  if( y < 0  ) return 0;
  if( y > height ) return height;
  return y;
}

//判断 矩形 标注的点是否在影像外面
function withoutAllRectang(data:any, width: number, height:number){
  const { handles }  = data;
  const { start, end } = handles;
  const withoutX = [start.x, end.x].every((value: number)=> {
    return value < 0 || value > width;
  })
  const withoutY = [start.y, end.y].every((value: number)=> {
    return value < 0 || value > height;
  })
  return withoutX || withoutY;
}

function handleRectangleData(data:any, width: number, height:number){
  const { handles }  = data;
  const { start, end } = handles;
  start.x = handleX(start.x, width);
  start.y = handleY(start.y, height);
  end.x = handleX(end.x, width);
  end.y = handleY(end.y, height);
}

function handleFreehandData(data:any, width: number, height:number){
  const { handles }  = data;
  const { points } = handles;
  points.forEach((item:any) => {
    item.x = handleX(item.x, width);
    item.y = handleY(item.y, height);
    if( Array.isArray(item.lines) && item.lines.length === 1  ){
      const lines  = [
        {
          x: item.lines[0].x,
          y: item.lines[0].y,
        }
      ]
      item.lines = lines;
    }
  })
}


const toolNameList = ["RectangleRoi", "FreehandRoi"];
class Cornerstone {
  element: any;
  imageBase64List: any[];
  tools:any[];
  currnetToolName: string;
  toolDisabled: boolean;
  width: number;
  height: number;
  measurementData: any;
  elementString: string;
  currentImageIndex: number;
  seriesUid: number;
  nidus:any;
  isView: boolean;
  seriesNumber: number;
  stack:any;
  scrollToIndex: Function;
  imageWidth: number;
  imageHeight: number;
  isCreate: boolean;
  currentUuid: string;
  isDown: boolean;
  private videoStore: any;
  constructor(options:any){
    this.seriesNumber = options?.seriesNumber || 0;
    this.seriesUid = options?.seriesUid;
    this.elementString = options?.element;
    this.element = document.querySelector(options?.element);
    this.currnetToolName = "";
    this.imageBase64List = options?.imageBase64List || [];
    this.tools = options?.tools || [];
    this.toolDisabled = options?.toolDisabled === undefined ? false : options?.toolDisabled;
    this.width = options.width || 800;
    this.height = options.height || 640;
    this.nidus = options?.nidus || {};
    this.isView = options?.isView;
    this.imageWidth = 0;
    this.imageHeight = 0;
    this.isCreate = false;
    cornerstone.enable(this.element);
    this.currentImageIndex = 0;
    this.currentUuid = "";
    this.isDown = false;
    // this.init();
    this.videoStore = useVideo()
    
    this.displayImage(0);
    this.scrollToIndex = cornerstoneTools.importInternal('util/scrollToIndex');
    // console.log("cornerstoneTools.EVENTS.", cornerstoneTools.EVENTS)
    this.element.addEventListener(cornerstoneTools.EVENTS.MEASUREMENT_ADDED, this.measurementAdded.bind(this));
    this.element.addEventListener(cornerstoneTools.EVENTS.MEASUREMENT_COMPLETED, this.completed.bind(this));
    this.element.addEventListener(cornerstoneTools.EVENTS.MEASUREMENT_MODIFIED, _.debounce(this.measurementModified.bind(this), 500));
    this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_CLICK, this.singleClick.bind(this));
    this.element.addEventListener(cornerstoneTools.EVENTS.MEASUREMENT_REMOVED, this.remove.bind(this));
    this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_MOVE, _.throttle(this.mouseMove.bind(this), 20));
    this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_DOWN, this.mouseDown.bind(this));
    this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_UP, this.mouseUp.bind(this));
  }

  nearBy( coords:any ){
    try {
      let [flag, data] = [false, null];
      const { state } = cornerstoneTools.store;
      state.tools.forEach( (tool:any)=> {
        const toolState = cornerstoneTools.getToolState(this.element, tool.name);
        if (toolState) {
          toolState.data.forEach((_data:any)=> {
            if( flag ) return;
            _data.toolName = tool.name
            data = _data
            flag = tool.pointNearTool(this.element, _data, coords);
          });
        }
      });
      return [flag, data];
    } catch (error) {

    }
  }
  mouseDown(){
    this.isDown = true;
  }
  mouseUp(){
    this.isDown = false;
  }
  mouseMove(e:any){
    if( this.isView || this.isDown ) return;
    const [isNear, data] = this.nearBy(e.detail.currentPoints.canvas) as any;
    if( isNear && data.uuid === this.currentUuid  ){//todo 靠近的、选中的才能编辑
      cornerstoneTools.setToolPassive(data.toolName, { mouseButtonMask: 1 })
    }else if(isNear && data.uuid !== this.currentUuid){
      cornerstoneTools.setToolEnabled(data.toolName, { mouseButtonMask: 1 })
    } else {
      if(this.currnetToolName === ''){
        cornerstoneTools.setToolEnabled('RectangleRoi');
        cornerstoneTools.setToolEnabled('FreehandRoi');
        cornerstoneTools.setToolActive('Wwwc', { mouseButtonMask: 1 });//默认工具
      }else{
        cornerstoneTools.setToolActive(this.currnetToolName, { mouseButtonMask: 1 });
      }
      // && (cornerstoneTools.isToolActiveForElement(this.element, this.currnetToolName))
      // && (cornerstoneTools.isToolActiveForElement(this.element, 'Wwwc'))
    }
    cornerstone.updateImage(this.element);
  }
  remove(e:any){
    // console.log("remove", e.detail)
    const { measurementData, toolName } = e.detail;
    if( this.isRectangle(toolName) ){
      handleRectangleData(measurementData, this.width, this.height)
    }
    this.addToolStateSingle(measurementData, toolName);
    this.completed(e);
  }

  singleClick(e:any){
    let flag = true;
    this.isDown = false
    const [isNear, data] = this.nearBy(e.detail.currentPoints.canvas) as any;
    toolNameList.forEach((toolName:string) => {
      const items:any = cornerstoneTools.getToolState(this.element, toolName);
      const states = (items?.data || []).slice();
      states.forEach((item:any) => {
        if( (item.active && flag) || ( isNear && data.uuid === item.uuid ) ){
          flag = false;
          bus.emit("Cornerstone.singleClick", item.uuid);
        }
      })
    })
  }
  isWithoutAll(data:any, toolName:string){
    let isWithoutAll = false;
    if( this.isRectangle(toolName) ){
      isWithoutAll =  withoutAllRectang(data, this.imageWidth, this.imageHeight);
    }
    if( this.isFreehand(toolName) ){
      
    }
    return isWithoutAll;
  }
  completed(e:any){
    let { measurementData, toolName } = e.detail;
    toolName = toolName === undefined ? "RectangleRoi" : toolName;
    if( measurementData ){
      if( this.isFreehand(toolName) ){
        handleFreehandData(measurementData, this.width, this.height)
      }
      bus.emit("Cornerstone.measurementCompleted", [toolName, JSON.parse(JSON.stringify(measurementData)), this.isRectangle(toolName), this.isFreehand(toolName) ]);
    }
  }
  //更新
  measurementModified(e:any){
    const { measurementData, toolName } = e.detail;
    if( measurementData && this.isGoodTool(toolName) ){  
      if( this.isFreehand(toolName) ){
        handleFreehandData(measurementData, this.width, this.height)
      }
      bus.emit("Cornerstone.measurementModified", [toolName, JSON.parse(JSON.stringify(measurementData)), this.isRectangle(toolName), this.isFreehand(toolName) ]);
    }
  }
  //添加
  measurementAdded(e:any){
    // const { measurementData, toolName } = e.detail;
    // if( measurementData && this.isGoodTool(toolName) ){
    //   bus.emit("Cornerstone.measurementAdded", [toolName, JSON.parse(JSON.stringify(measurementData)), this.imageWidth, this.imageHeight]);
    // }
  }
  init(){
    const imageIds = this.imageBase64List.map((imageBase64, index)=>{
      return `example://${this.seriesUid}/${(index+1)}.jpg`
    })
    this.stack = {
      seriesDescription: "",
      stackId: this.seriesUid,
      imageIds,
      seriesIndex: this.seriesNumber,
      currentImageIdIndex: 0,
      frameRate: 0,
    }
    cornerstone.registerImageLoader('example', (imageId:any) :any =>{
      const index = imageIds.findIndex(_imageId=> imageId === _imageId)
      return this.getExampleImage(imageId, this.imageBase64List[index]);
    });
    cornerstoneTools.addStackStateManager(this.element, ['stack'])
    cornerstoneTools.addToolState(this.element, 'stack', this.stack)
    cornerstoneTools.stackPrefetch.enable(this.element)
  }
  // displayImage(imageIndex: number = 0, callback:Function = ()=>{}){
  //   if( imageIndex < 0 || imageIndex >= this.imageBase64List.length  ) return;
  //   const imageId = `example://${this.seriesUid}/${(imageIndex+1)}.jpg`;
  //   cornerstone.loadAndCacheImage(imageId).then((image:any)=> {
  //     setTimeout(()=>{
  //       this.currentImageIndex = imageIndex;
  //       cornerstone.displayImage(this.element, image);
  //       callback();
  //     })
  //   });
  // }
  // setScrollToIndex(index:number){
  //   this.scrollToIndex(this.element, index);
  // }
  displayImage(imageIndex: number, callback:Function = ()=>{}){
    if( imageIndex < 0 || imageIndex >= this.imageBase64List.length  ) return;
    const img = this.imageBase64List[imageIndex || 0];
    cornerstone.registerImageLoader('example', (imageId:any) :any =>{
      return this.getExampleImage(imageId, img);
    });
    cornerstone.loadAndCacheImage(`example://${this.seriesUid}/${(imageIndex+1)}.jpg`).then((image:any)=> {
      setTimeout(()=>{
        this.imageWidth = image.width;
        this.imageHeight = image.height;
        this.currentImageIndex = imageIndex;
        cornerstone.displayImage(this.element, image);
        callback();
      })
    });
    
  }
  setScrollToIndex(index:number){
    this.displayImage(index);
  }
  
  getExampleImage(imageId:any, imageBase64:any) {
    let [width, height] = [this.width, this.height];
    // const img = document.createElement("img");
    const img = new Image();
    img.srcset = imageBase64;
    // 使用Image对象获取图像长和宽，并准备转化为canvas对象
    img.width = width;
    img.height = height;
  
    function loadPixelData () {
      // 用canvas获取图像数据的像素矩阵（数组）
      const canvas = document.createElement("canvas");
      canvas.width = width;
      canvas.height = height;
      canvas.getContext("2d")?.drawImage(img, 0, 0);
      const pixelData_obj:any = canvas.getContext("2d")?.getImageData(0,0,canvas.width,canvas.height);    // 获取画布上的图像像素矩阵
      const pixelData = pixelData_obj.data;
      return pixelData;
    }
    // fetch(imageBase64)
    // .then(res => res.arrayBuffer())
    // .then((res) => {
    //   const arrBuffer1 = new Uint8ClampedArray(res);
    //   console.log(arrBuffer1, "arrBuffer1");
    // })
    
    const image = {
      imageId: imageId,
      minPixelValue : 0,
      maxPixelValue : 255,
      slope: 1.0,
      intercept: 0,
      windowCenter : 127,
      windowWidth : 256,
      getPixelData: loadPixelData,	// 要求图像的像素矩阵
      rows: height,
      columns: width,
      height: height,
      width: width,
      color: true,	// 注意：为彩色图像
      rgba: true,		// 注意：使用rgba表示（canvas直接导出）
      columnPixelSpacing: .8984375,
      rowPixelSpacing: .8984375,
      sizeInBytes: width * height * 4
    };
    return {
      promise: new Promise((resolve) => {
        resolve(image);
      }),
      cancelFn: undefined
    };
  }
  setToolDisabled( toolName:string ){
    this.toolDisabled = true
    const tool = cornerstoneTools[`${toolName}Tool`];
    // cornerstoneTools.removeTool(toolName);
    cornerstoneTools.setToolDisabled(toolName);
  }
  setToolName(toolName:string){
    this.currnetToolName = toolName
  }
  setToolActive(toolName:string){
    const tool = cornerstoneTools[`${toolName}Tool`];
    cornerstoneTools.setToolActive(toolName, { mouseButtonMask: 1 });
    if( this.currnetToolName === "RectangleRoi" ){
      cornerstoneTools.setToolEnabled("FreehandRoi", { mouseButtonMask: 1 })
    } else if(this.currnetToolName === "FreehandRoi"){
      cornerstoneTools.setToolEnabled("RectangleRoi", { mouseButtonMask: 1 })
    }
  }
  setToolEnabled(toolName:string){
    cornerstoneTools.setToolEnabled(toolName, { mouseButtonMask: 1 });
  }

  setToolPassive(toolName:string){
    cornerstoneTools.setToolPassive(toolName, { mouseButtonMask: 1 });
  }

  toggleToolDisabled(statusText: string){
    if( statusText === 'enabled'  ){
      this.toolDisabled = true;
      cornerstoneTools.setToolEnabled("RectangleRoi", { mouseButtonMask: 1 })
      cornerstoneTools.setToolEnabled("FreehandRoi", { mouseButtonMask: 1 })
    } 
    if( statusText === "passive" ){
      cornerstoneTools.setToolPassive("RectangleRoi", { mouseButtonMask: 1 });
      cornerstoneTools.setToolPassive("FreehandRoi", { mouseButtonMask: 1 });
    }
    if( statusText === "active" ){
      cornerstoneTools.setToolActive(this.currnetToolName, { mouseButtonMask: 1 });
      if( this.currnetToolName === "RectangleRoi" ){
        cornerstoneTools.setToolEnabled("FreehandRoi", { mouseButtonMask: 1 })
      } else {
        cornerstoneTools.setToolEnabled("RectangleRoi", { mouseButtonMask: 1 })
      }
    }
  }
  //调窗工具
  toggleToolDisabledWwwc( disabled:boolean, toolName:string ){
    if( disabled ){
      cornerstoneTools.setToolDisabled(toolName, { mouseButtonMask: 1 })
    } else {
      cornerstoneTools.setToolActive(toolName, { mouseButtonMask: 1 });
    }
  }

  setWL(wl, ww) {
    const viewport = cornerstone.getViewport(this.element)
    if (!viewport) return
    viewport.voi.windowCenter = wl * 1
    viewport.voi.windowWidth = ww * 1
    cornerstone.setViewport(this.element, viewport)
  }

  //单个病灶数据添加到state里
  addToolStateSingle( data: any, toolName:string ){
    const imageId = `example://${this.seriesUid}/${this.currentImageIndex + 1}.jpg`;
    cornerstoneTools.globalImageIdSpecificToolStateManager.addImageIdToolState(imageId, toolName, data);
    cornerstone.updateImage(this.element);
  }

  clearToolState(){
    const toolState:any = cornerstoneTools.globalImageIdSpecificToolStateManager.toolState
    Object.keys(toolState).forEach((key:any) => {
      cornerstoneTools.globalImageIdSpecificToolStateManager.clearImageIdToolState(key)
    })
    // console.log("after clear",cornerstoneTools.globalImageIdSpecificToolStateManager.toolState)
  }
  updateImage(){
    cornerstone.updateImage(this.element)
  }
  resize() {
    cornerstone.resize(this.element);
  }
  //初始化的时候执行一次
  addToolState(nidusList:any, isView:boolean){
    this.isView = isView
    nidusList.child.forEach((item: any, index:number) => {
      const { child } = item;
      child.forEach((it:any)=> {
        const { data, toolName, labelIndex } = it
        // this.setToolActive(toolName);
        this.setToolEnabled(toolName)
        const imageId = `example://${this.seriesUid}/${labelIndex}.jpg`
        cornerstoneTools.globalImageIdSpecificToolStateManager.addImageIdToolState(imageId, toolName, data);
      })
    });
    //添加单帧列表的工具
    const singleList = this.videoStore.getSingleAnnoListBySuid(nidusList.id);
    singleList.map((its: any) => {
      const { data, toolName, labelIndex } = its
      this.setToolEnabled(toolName)
      const imageId = `example://${this.seriesUid}/${labelIndex}.jpg`
      cornerstoneTools.globalImageIdSpecificToolStateManager.addImageIdToolState(imageId, toolName, data);
    })
    console.log("added",cornerstoneTools.globalImageIdSpecificToolStateManager.toolState)
    //恢复之前工具
    if(this.currnetToolName === '' || this.toolDisabled){
      cornerstoneTools.setToolPassive('RectangleRoi')
      cornerstoneTools.setToolPassive('FreehandRoi')
    }else{
      this.setToolActive(this.currnetToolName);
    }

    cornerstone.updateImage(this.element);
    if( isView ){
      setTimeout(()=>{
        cornerstoneTools.setToolEnabled('RectangleRoi')
        cornerstoneTools.setToolEnabled('FreehandRoi')
      },100)
    }
  }
  setToolVisible(item:any){
    const { toolName, hide } = item;
    const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.toolState
    for(let ts in toolState){
      let data = toolState[ts][toolName]?.data || []
      data.forEach((dataItem:any)=> {
        if(dataItem.uuid === item.data.uuid){
          if( toolName ){
            dataItem.visible = !hide
          }
        }
      });
    }
    cornerstone.updateImage(this.element);
  }
  setStateColor(item:any, color:string){
    const { toolName } = item;
    const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.toolState
    for(let ts in toolState){
      let data = toolState[ts][toolName]?.data || []
      data.forEach((dataItem:any)=> {
        if(dataItem.uuid === item.data.uuid){
          dataItem.color = color;
          // item.data.active? (this.currentUuid = item.data.uuid) : (this.currentUuid = '')
        }
      });
    }
    cornerstone.updateImage(this.element);
  }
  setCurrentUuid(uuid: any){
    this.currentUuid = uuid
  }
  removeToolState(item:any){
    const { toolName } = item;
    const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.toolState
    for(let ts in toolState){
      let data = toolState[ts][toolName]?.data || []
      if(data.length === 0) continue
      toolState[ts][toolName].data = data.filter((it:any) => item.data.uuid !== it.uuid)
    }
    cornerstone.updateImage(this.element);
  }
  isRectangle(toolName:string){
    return ["RectangleRoi"].includes(toolName);
  }
  isFreehand(toolName:string){
    return ["FreehandRoi"].includes(toolName);
  }
  isGoodTool(toolName:string){
    return this.isRectangle(toolName) || this.isFreehand(toolName);
  }
}

export default Cornerstone;
